"""
免息额度和币种折算率模块
获取免息额度和币种折算率等级信息
"""
import time
from typing import Dict, List, Optional
from datetime import datetime, timedelta
from loguru import logger

try:
    import okx.PublicData as PublicData
except ImportError:
    logger.warning("okx SDK未安装，请运行: pip install okx")
    PublicData = None


class DiscountInfoManager:
    """免息额度和币种折算率管理器"""
    
    # 限速配置：2次/2s
    RATE_LIMIT_REQUESTS = 2
    RATE_LIMIT_WINDOW = 2.0  # 秒
    
    def __init__(self, sandbox: bool = True):
        """
        初始化免息额度和币种折算率管理器
        
        Args:
            sandbox: 是否使用模拟盘，True=模拟盘(1)，False=实盘(0)
        """
        if PublicData is None:
            raise ImportError("okx SDK未安装，请运行: pip install okx")
        
        self.sandbox = sandbox
        flag = "1" if sandbox else "0"
        
        # 初始化OKX公共数据API
        self.public_api = PublicData.PublicAPI(flag=flag)
        
        # 限速控制
        self.request_times: List[float] = []  # 请求时间戳列表
        
        # 数据缓存
        self.discount_info_cache: Optional[List[Dict]] = None
        self.cache_expire_time: Optional[datetime] = None
        self.cache_duration = timedelta(hours=1)  # 缓存1小时
        
        logger.info(f"免息额度和币种折算率管理器已初始化 (模式: {'模拟盘' if sandbox else '实盘'})")
    
    def _check_rate_limit(self):
        """
        检查并执行限速
        限速规则：2次/2s (IP)
        """
        now = time.time()
        
        # 移除2秒前的请求记录
        self.request_times = [t for t in self.request_times 
                             if now - t < self.RATE_LIMIT_WINDOW]
        
        # 如果达到限速上限，等待
        if len(self.request_times) >= self.RATE_LIMIT_REQUESTS:
            oldest_request = self.request_times[0]
            wait_time = self.RATE_LIMIT_WINDOW - (now - oldest_request)
            
            if wait_time > 0:
                logger.debug(f"触发限速，等待 {wait_time:.2f} 秒")
                time.sleep(wait_time)
                # 重新计算
                now = time.time()
                self.request_times = [t for t in self.request_times 
                                     if now - t < self.RATE_LIMIT_WINDOW]
        
        # 记录本次请求
        self.request_times.append(now)
    
    def get_discount_info(self, use_cache: bool = True) -> List[Dict]:
        """
        获取免息额度和币种折算率等级
        
        Args:
            use_cache: 是否使用缓存
            
        Returns:
            折算率信息列表，每个币种包含以下字段：
            - ccy: 币种
            - amt: 免息额度
            - discountLv: 折算率等级
            - discountInfo: 折算率详细信息列表
                - discountRate: 折算率
                - maxAmt: 最大借币量
                - minAmt: 最小借币量
        """
        # 检查缓存
        if use_cache and self.discount_info_cache is not None:
            if self.cache_expire_time and datetime.now() < self.cache_expire_time:
                logger.debug("从缓存获取免息额度和折算率信息")
                return self.discount_info_cache
        
        # 执行限速检查
        self._check_rate_limit()
        
        try:
            logger.info("获取免息额度和币种折算率等级")
            result = self.public_api.discount_interest_free_quota()
            
            # 检查响应
            if result.get("code") != "0":
                error_msg = result.get("msg", "未知错误")
                logger.error(f"获取免息额度和折算率失败: {error_msg}")
                raise RuntimeError(f"API错误: {error_msg}")
            
            # 提取数据
            data_list = result.get("data", [])
            logger.info(f"获取免息额度和折算率成功: {len(data_list)} 个币种")
            
            # 更新缓存
            if use_cache:
                self.discount_info_cache = data_list
                self.cache_expire_time = datetime.now() + self.cache_duration
            
            return data_list
            
        except Exception as e:
            logger.error(f"获取免息额度和折算率异常: {e}")
            raise
    
    def get_currency_discount_info(self, ccy: str, use_cache: bool = True) -> Optional[Dict]:
        """
        获取指定币种的折算率信息
        
        Args:
            ccy: 币种，如 BTC, ETH
            use_cache: 是否使用缓存
            
        Returns:
            币种折算率信息字典，如果不存在返回None
        """
        discount_info_list = self.get_discount_info(use_cache)
        
        for info in discount_info_list:
            if info.get("ccy") == ccy:
                return info
        
        logger.warning(f"未找到币种 {ccy} 的折算率信息")
        return None
    
    def get_currency_details(self, ccy: str) -> Dict:
        """
        获取币种详细信息（包含格式化数据）
        
        Args:
            ccy: 币种
            
        Returns:
            详细信息字典：
            - ccy: 币种
            - interest_free_quota: 免息额度
            - discount_level: 折算率等级
            - discount_rates: 折算率详细信息列表
        """
        info = self.get_currency_discount_info(ccy)
        
        if not info:
            raise ValueError(f"无法获取币种 {ccy} 的折算率信息")
        
        # 提取折算率详细信息
        discount_info = info.get("discountInfo", [])
        discount_rates = []
        
        for item in discount_info:
            discount_rates.append({
                "discount_rate": float(item.get("discountRate", 0)),
                "max_amount": float(item.get("maxAmt", 0)),
                "min_amount": float(item.get("minAmt", 0)),
            })
        
        return {
            "ccy": ccy,
            "interest_free_quota": float(info.get("amt", 0)),
            "discount_level": int(info.get("discountLv", 0)),
            "discount_rates": discount_rates,
        }
    
    def get_currencies_by_discount_level(self, level: int) -> List[Dict]:
        """
        获取指定折算率等级的所有币种
        
        Args:
            level: 折算率等级
            
        Returns:
            币种列表
        """
        discount_info_list = self.get_discount_info()
        
        currencies = [
            info for info in discount_info_list
            if int(info.get("discountLv", 0)) == level
        ]
        
        return currencies
    
    def get_high_discount_currencies(self, min_rate: float = 0.9) -> List[Dict]:
        """
        获取高折算率的币种
        
        Args:
            min_rate: 最小折算率，默认0.9
            
        Returns:
            高折算率币种列表
        """
        discount_info_list = self.get_discount_info()
        
        high_discount_currencies = []
        
        for info in discount_info_list:
            discount_info = info.get("discountInfo", [])
            if discount_info:
                # 获取最高折算率
                max_rate = max(float(item.get("discountRate", 0)) for item in discount_info)
                if max_rate >= min_rate:
                    high_discount_currencies.append({
                        "ccy": info.get("ccy"),
                        "max_discount_rate": max_rate,
                        "interest_free_quota": float(info.get("amt", 0)),
                        "discount_level": int(info.get("discountLv", 0)),
                    })
        
        # 按折算率排序
        high_discount_currencies.sort(key=lambda x: x["max_discount_rate"], reverse=True)
        
        return high_discount_currencies
    
    def get_interest_free_currencies(self, min_quota: float = 0) -> List[Dict]:
        """
        获取有免息额度的币种
        
        Args:
            min_quota: 最小免息额度，默认0
            
        Returns:
            有免息额度的币种列表
        """
        discount_info_list = self.get_discount_info()
        
        interest_free_currencies = []
        
        for info in discount_info_list:
            quota = float(info.get("amt", 0))
            if quota > min_quota:
                interest_free_currencies.append({
                    "ccy": info.get("ccy"),
                    "interest_free_quota": quota,
                    "discount_level": int(info.get("discountLv", 0)),
                })
        
        # 按免息额度排序
        interest_free_currencies.sort(key=lambda x: x["interest_free_quota"], reverse=True)
        
        return interest_free_currencies
    
    def compare_currencies(self, currencies: List[str]) -> List[Dict]:
        """
        比较多个币种的折算率信息
        
        Args:
            currencies: 币种列表
            
        Returns:
            比较结果列表
        """
        results = []
        
        for ccy in currencies:
            try:
                details = self.get_currency_details(ccy)
                
                # 获取最高折算率
                max_rate = 0
                if details["discount_rates"]:
                    max_rate = max(item["discount_rate"] for item in details["discount_rates"])
                
                results.append({
                    "ccy": ccy,
                    "interest_free_quota": details["interest_free_quota"],
                    "discount_level": details["discount_level"],
                    "max_discount_rate": max_rate,
                })
            except Exception as e:
                logger.error(f"获取 {ccy} 信息失败: {e}")
        
        return results
    
    def clear_cache(self):
        """清除缓存"""
        self.discount_info_cache = None
        self.cache_expire_time = None
        logger.info("已清除免息额度和折算率缓存")
    
    def get_cache_stats(self) -> Dict:
        """
        获取缓存统计信息
        
        Returns:
            缓存统计字典
        """
        is_cached = self.discount_info_cache is not None
        is_valid = False
        
        if is_cached and self.cache_expire_time:
            is_valid = datetime.now() < self.cache_expire_time
        
        return {
            "is_cached": is_cached,
            "is_valid": is_valid,
            "cache_duration_hours": self.cache_duration.total_seconds() / 3600,
        }


# 便捷函数
def get_discount_info(sandbox: bool = True) -> List[Dict]:
    """
    便捷函数：获取免息额度和币种折算率等级
    
    Args:
        sandbox: 是否使用模拟盘
        
    Returns:
        折算率信息列表
    """
    manager = DiscountInfoManager(sandbox=sandbox)
    return manager.get_discount_info()


def get_currency_details(ccy: str, sandbox: bool = True) -> Dict:
    """
    便捷函数：获取币种详细信息
    
    Args:
        ccy: 币种
        sandbox: 是否使用模拟盘
        
    Returns:
        详细信息字典
    """
    manager = DiscountInfoManager(sandbox=sandbox)
    return manager.get_currency_details(ccy)


def get_high_discount_currencies(min_rate: float = 0.9, sandbox: bool = True) -> List[Dict]:
    """
    便捷函数：获取高折算率的币种
    
    Args:
        min_rate: 最小折算率
        sandbox: 是否使用模拟盘
        
    Returns:
        高折算率币种列表
    """
    manager = DiscountInfoManager(sandbox=sandbox)
    return manager.get_high_discount_currencies(min_rate)


def get_interest_free_currencies(min_quota: float = 0, sandbox: bool = True) -> List[Dict]:
    """
    便捷函数：获取有免息额度的币种
    
    Args:
        min_quota: 最小免息额度
        sandbox: 是否使用模拟盘
        
    Returns:
        有免息额度的币种列表
    """
    manager = DiscountInfoManager(sandbox=sandbox)
    return manager.get_interest_free_currencies(min_quota)
